<?php
// +-----------------+--------------------------------+------+-----+---------+----------------+
// | Field           | Type                           | Null | Key | Default | Extra          |
// +-----------------+--------------------------------+------+-----+---------+----------------+
// | id              | int(11)                        | NO   | PRI | NULL    | auto_increment |
// | name            | varchar(60)                    | NO   |     |         |                |
// | password        | varchar(64)                    | NO   |     |         |                |
// | nickname        | varchar(50)                    | YES  |     |         |                |
// | email           | varchar(100)                   | YES  |     |         |                |
// | url             | varchar(100)                   | YES  |     |         |                |
// | avatar          | varchar(200)                   | YES  |     |         |                |
// | gender          | enum('secret','male','female') | YES  |     | secret  |                |
// | birthday        | date                           | YES  |     | NULL    |                |
// | signature       | varchar(40)                    | YES  |     |         |                |
// | last_login_ip   | bigint(20) unsigned            | YES  |     | 0       |                |
// | last_login_time | int(11) unsigned               | YES  |     | 0       |                |
// | activation_key  | varchar(60)                    | YES  |     |         |                |
// | status          | tinyint(1)                     | YES  |     | 1       |                |
// | mobile          | varchar(20)                    | YES  |     |         |                |
// | member_id       | int(11) unsigned               | YES  |     | 0       |                |
// | create_time     | int(11) unsigned               | YES  |     | 0       |                |
// | update_time     | int(11) unsigned               | YES  |     | 0       |                |
// | delete_time     | int(11) unsigned               | YES  |     | 0       |                |
// +-----------------+--------------------------------+------+-----+---------+----------------+
namespace app\admin\model;

use think\facade\Config;
use think\facade\Session;
use app\admin\model\Base;
use app\admin\model\AuthGroupAccess as AccessModel;
use app\admin\validate\Member as Validate;
class Member extends Base
{
    /**
     * 与AuthGroup BelongsTo关联设置
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @return   array              [description]
     */
    public function group()
    {
        return $this->belongsTo('AuthGroup', 'group_id')->bind([
                'group_title'  => 'title',
                'is_super_group'  => 'is_super',
            ]);
    }

    /**
     * 搜索方法
     * @Author   Laifuzi
     * @DateTime 2018-06-06
     * @param    array      $param     查询参数
     * @param    integer    $page_rows 每页显示数量
     * @return   Paginate              分页查询结果
     */
    function minePaginate($param, $page_rows = 0)
    {
        if($page_rows < 1){
            $page_rows = Config::get('paginate.list_rows');
        }

        $map = $this->parseSearchParam($param);

        $config = [];
        $config["query"] = $param;
        // 分页参数名是 page ，paginate方法内有获取到该值的方法
        $page = 1;
        if(isset($param["page"])){
            $page = intval($param["page"]);
        }
        $config["page"] = $page;

        $select_fields = ['id', 'name', 'nickname', 'password', 'email', 'avatar', 'status', 'group_id',
            "IF(last_login_ip!='' && last_login_ip>0, INET_NTOA(last_login_ip), '') AS last_ip",
            "FROM_UNIXTIME(last_login_time, '%Y-%m-%d %H:%i') AS last_login_time",
            'create_time'];

        $order_type = '';
        if(isset($param['order'])){
            $order_type = $param['order'];
        }
        $order_str = $this->queryOrderStr($order_type);

        $paginate = $this->with('group')->field($select_fields)->where($map)->order($order_str)->paginate($page_rows, false, $config);
        return $paginate;
    }

    /**
     * 添加新管理员
     * @Author   Laifuzi
     * @DateTime 2018-06-06
     * @param    array     $data 用户数据
     * @return   array
     */
    public function createItem($data)
    {
        $res = ['status' => false, 'data' => [], 'msg' => "添加管理员失败"];

        $data['avatar'] = $this->defaultAvatar();
        $validate = new Validate;
        if(!$validate->check($data)){
            $res['msg'] = $validate->getError();
            return $res;
        }

        $data['password'] = $this->md5Password($data['password']);
        $this->data($data)->allowField(true)->save();
        $id = $this->id;

        if(isset($data['group_id'])){
            $AccessModel = new AccessModel;
            $AccessModel->createOrUpdateUserAccess($id, $data['group_id']);
        }

        $res = [
            'status' => true,
            'msg' => '添加管理员成功',
            'data' => ['id' => $id],
        ];
        return $res;
    }

    /**
     * 更新管理员信息
     * @Author   Laifuzi
     * @DateTime 2018-06-06
     * @param    array     $data 用户数据
     * @return   array
     */
    public function updateItem($data)
    {
        $res = ['status' => false, 'msg' => '更新管理员信息失败', 'data' => []];
        $validate = new Validate;
        if(!$validate->check($data)){
            $res['msg'] = $validate->getError();
            return $res;
        }

        if(isset($data['password'])){
            if(empty($data['password'])){
                unset($data['password']);
            }else{
                $data['password'] = $this->md5Password($data['password']);
            }
        }
        $this->data($data)->isUpdate(true)->allowField(true)->save();

        if(isset($data['group_id'])){
            $AccessModel = new AccessModel;
            $AccessModel->createOrUpdateUserAccess($this->id, $data['group_id']);
        }

        $res = [
            'status' => true,
            'msg' => '更新管理员成功',
            'data' => ['id' => $this->id],
        ];
        return $res;
    }

    /**
     * 查找或创建管理员记录
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @param    array              $data [description]
     * @return   array                    [description]
     */
    public function findOrCreate($data)
    {
        $res = ['status' => false, 'data' => [], 'msg' => '查找或添加管理员用户失败'];
        if(empty($data['name'])){
            $res['msg'] = '登录名不能为空';
            return $res;
        }

        $item = $this->where('name', $data['name'])->find();
        if(!empty($item)){
            $res = [
                'status' => true,
                'data' => ['id' => $item['id']],
                'msg' => '查找到该管理员记录',
            ];
            return $res;
        }
        return $this->createItem($data);
    }

    public function findOne($id){
        $select_fields = ['id', 'name', 'nickname', 'password', 'email', 'avatar', 'status', 'group_id',
            'INET_NTOA(last_login_ip) AS last_login_ip', "FROM_UNIXTIME(last_login_time, '%Y-%m-%d %H:%i') AS last_login_time", 'create_time', 'update_time'];
        return $this->with('group')->where('id', $id)->find();
    }

    /**
     * 管理员默认头像
     * @Author   Laifuzi
     * @DateTime 2018-06-06
     * @return   [type]     [description]
     */
    public function defaultAvatar(){
        return '/static/admin/images/default_avatar.png';
    }

    /**
     * 登录方法
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @param    string             $name     登录名
     * @param    string             $password 登录密码
     * @return   array
     */
    public function doLogin($name, $password){
        $res = ['status' => false, 'msg' => '登录失败', 'data' => []];
        if(empty($name)){
            $res['msg'] = '登录名不能为空';
            return $res;
        }

        $select_fields = ['id', 'name', 'nickname', 'password', 'email', 'avatar', 'group_id', 'status',
            'INET_NTOA(last_login_ip) AS last_login_ip', "FROM_UNIXTIME(last_login_time, '%Y-%m-%d %H:%i') AS last_login_time",
            'create_time'];


        $item = $this->with('group')->field($select_fields)->where('name', $name)->find();
        if(empty($item)){
            $res['msg'] = '登录用户不存在';
            return $res;
        }else if($item['password'] != $this->md5Password($password)){
            $res['msg'] = '登录用户名或密码错误';
            return $res;
        }else if($item['status'] != true){
            $res['msg'] = '您的账号已被冻结';
            return $res;
        }
        // 返回结果里不包含密码
        unset($item['password']);

        $req = request();
        $data = ["last_login_ip" => ip2long($req->ip()), "last_login_time" => time()];
        $this->where('id', $item['id'])->update($data);
        return ['status' => true, 'msg' => '登录成功', 'data' => $item];
    }

    /**
    * 更新用户密码
    * @Author zhanghong
    * @Date   2016-12-22
    * @param  [array]       $data         密码信息
    * @param  boolean       $only_active  是否只查询有效用户
    * @return [array]                     操作是否成功
    */
    public function changePassword($data, $only_active = true){
        $res = ["status" => false, "msg" => "密码更新失败"];

        // data包含 password(新密码), old_password(旧密码)，confirm_password(确认密码)
        $id = intval($data['id']);
        $item = $this->where('id', $id)->find();
        if(empty($item)){
            $res['msg'] = '未找到当前管理员用户';
            return $res;
        }else if($only_active && $item['status'] != true){
            $res['msg'] = '已冻结管理员用户不能修改密码';
            // return $res;
        }else if($item['password'] != $this->md5Password($data["old_password"])){
            $res['msg'] = "旧密码错误";
            return $res;
        }

        return $this->updateItem($data);
    }

    /**
     * 重新加载登录信息
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @param    string             $name     登录名
     * @param    string             $password 登录密码
     * @return   boolean
     */
    public function reloadLoginInfo($id){
        $select_fields = ['id', 'name', 'nickname', 'password', 'email', 'avatar', 'group_id',
            'INET_NTOA(last_login_ip) AS last_login_ip', "FROM_UNIXTIME(last_login_time, '%Y-%m-%d %H:%i') AS last_login_time",
            'create_time'];

        $member = $this->with('group')->field($select_fields)->where('status', 1)->where('id', $id)->find();
        Session::set("member", $member);
        return true;
    }

    /**
    * 验证用户登录密码
    * @Author zhanghong
    * @Date   2017-01-01
    * @param  integer    $id       用户ID
    * @param  string     $password 登录密码
    * @return string               true/false
    */
    public function validPassword($id, $password){
        $item = $this->where("id", $id)->find();
        if(empty($item)){
            return 'false';
        }else if($item['status'] < 1){
            return 'false';
        }else if($item['password'] != $this->md5Password($password)){
            return 'false';
        }
        return "true";
    }

    /**
     * 唯一值字段列表
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @return   array             [description]
     */
    protected function uniqueFileList()
    {
        return ['name', 'email', 'mobile'];
    }

    /**
     * 搜索排序方式
     * @Author   zhanghong(Laifuzi)
     * @DateTime 2018-06-07
     * @param    string             $param 排序方式
     * @return   string                    [description]
     */
    protected function queryOrderStr($order_type = '')
    {
        return 'id ASC';
    }

    /**
     * 生成密码加密结果
     * @Author   Laifuzi
     * @DateTime 2018-06-06
     * @param    string     $password 用户输入密码
     * @param    string     $authcode 加密key
     * @return   string               加密后的密码
     */
    private function md5Password($password, $authcode = '')
    {
        if(empty($authcode)){
            $authcode = Config::get('app.authcode');
        }
        $result = "###".md5(md5($authcode.$password));
        return $result;
    }

    private function parseSearchParam($param)
    {
        $map = [];
        foreach ($param as $key => $value) {
            if(!is_array($value)){
                $value = trim($value);
            }
            switch ($key) {
            case "keyword":
                if(empty($value)){
                    continue;
                }else{
                    $keyword = "%{$value}%";
                }
                $map[] = ["name|nickname|email|mobile", "like", $keyword];
                break;
            }
        }
        return $map;
    }
}